"""
@Author: li
@Email: lijianqiao2906@live.com
@FileName: user.py
@DateTime: 2025/07/05
@Docs: 核心权限管理模型 - 根据数据字典3.3重新设计
"""

from tortoise import fields

from app.models.base import BaseModel


class User(BaseModel):
    """用户模型 - 3.3.1 User 表"""

    # 基本信息字段
    username = fields.CharField(max_length=50, unique=True, description="用户名")
    email = fields.CharField(max_length=100, unique=True, description="邮箱")
    phone = fields.CharField(max_length=20, unique=True, null=True, description="手机号")
    password_hash = fields.CharField(max_length=255, description="密码哈希")

    # 用户扩展信息
    avatar_url = fields.CharField(max_length=500, null=True, description="头像URL")
    nickname = fields.CharField(max_length=100, null=True, description="昵称")
    bio = fields.TextField(null=True, description="个人简介")

    # 状态字段（继承BaseModel的is_active，并增加超管字段）
    is_superuser = fields.BooleanField(default=False, description="是否超管")
    last_login_at = fields.DatetimeField(null=True, description="最后登录时间", db_index=True)

    # 描述字段
    description = fields.TextField(null=True, description="描述")

    # 多对多关系
    roles = fields.ManyToManyField("models.Role", related_name="users", description="用户角色")

    class Meta:  # type: ignore
        table = "sys_user"
        table_description = "系统用户表"

    def __str__(self) -> str:
        return f"User(username={self.username})"

    def to_dict(self, exclude_sensitive: bool = True) -> dict:
        """转换为字典，默认排除敏感字段"""
        data = super().to_dict(exclude_sensitive=exclude_sensitive)
        data.update(
            {
                "username": self.username,
                "email": self.email,
                "phone": self.phone,
                "avatar_url": self.avatar_url,
                "nickname": self.nickname,
                "bio": self.bio,
                "is_superuser": self.is_superuser,
                "last_login_at": self.last_login_at,
                "description": self.description,
            }
        )

        # 排除敏感字段
        if exclude_sensitive:
            data.pop("password_hash", None)

        return data


class Role(BaseModel):
    """角色模型 - 3.3.2 Role 表"""

    name = fields.CharField(max_length=50, unique=True, description="角色名称")
    code = fields.CharField(max_length=50, unique=True, description="角色编码")
    sort_order = fields.IntField(default=0, description="排序", db_index=True)
    description = fields.TextField(null=True, description="描述")

    # 多对多关系
    permissions = fields.ManyToManyField("models.Permission", related_name="roles", description="角色权限")

    class Meta:  # type: ignore
        table = "sys_role"
        table_description = "系统角色表"

    def __str__(self) -> str:
        return f"Role(name={self.name})"

    def to_dict(self, exclude_sensitive: bool = False) -> dict:
        """转换为字典"""
        data = super().to_dict(exclude_sensitive=exclude_sensitive)
        data.update(
            {
                "name": self.name,
                "code": self.code,
                "sort_order": self.sort_order,
                "description": self.description,
            }
        )
        return data


class Permission(BaseModel):
    """权限模型 - 3.3.3 Permission 表"""

    name = fields.CharField(max_length=100, description="权限名称")
    code = fields.CharField(max_length=100, unique=True, description="权限编码")
    module = fields.CharField(max_length=100, description="所属模块", db_index=True, default="system")
    type = fields.CharField(max_length=20, description="权限类型", db_index=True)
    resource = fields.CharField(max_length=100, null=True, description="资源标识")
    action = fields.CharField(max_length=50, null=True, description="操作类型")

    # 树形结构
    parent_id = fields.BigIntField(null=True, description="父权限ID", db_index=True)

    # 排序和状态
    sort_order = fields.IntField(default=0, description="排序", db_index=True)
    description = fields.TextField(null=True, description="描述")

    class Meta:  # type: ignore
        table = "sys_permission"
        table_description = "系统权限表"

    def __str__(self) -> str:
        return f"Permission(code={self.code})"

    def to_dict(self, exclude_sensitive: bool = False) -> dict:
        """转换为字典"""
        data = super().to_dict(exclude_sensitive=exclude_sensitive)
        data.update(
            {
                "name": self.name,
                "code": self.code,
                "module": self.module,
                "type": self.type,
                "resource": self.resource,
                "action": self.action,
                "parent_id": self.parent_id,
                "sort_order": self.sort_order,
                "description": self.description,
            }
        )
        return data


class Menu(BaseModel):
    """菜单模型 - 3.3.4 Menu 表"""

    name = fields.CharField(max_length=100, description="菜单名称")
    title = fields.CharField(max_length=100, description="菜单标题")
    path = fields.CharField(max_length=200, null=True, description="路由路径")
    component = fields.CharField(max_length=200, null=True, description="组件路径")
    icon = fields.CharField(max_length=100, null=True, description="图标")

    # 树形结构
    parent_id = fields.BigIntField(null=True, description="父菜单ID", db_index=True)

    # 菜单类型和属性
    type = fields.CharField(max_length=20, description="菜单类型", db_index=True)
    is_hidden = fields.BooleanField(default=False, description="是否隐藏")
    is_keepalive = fields.BooleanField(default=False, description="是否缓存")

    # 排序和权限
    sort_order = fields.IntField(default=0, description="排序", db_index=True)
    permission_code = fields.CharField(max_length=100, null=True, description="权限编码", db_index=True)

    description = fields.TextField(null=True, description="描述")

    class Meta:  # type: ignore
        table = "sys_menu"
        table_description = "系统菜单表"

    def __str__(self) -> str:
        return f"Menu(title={self.title})"

    def to_dict(self, exclude_sensitive: bool = False) -> dict:
        """转换为字典"""
        data = super().to_dict(exclude_sensitive=exclude_sensitive)
        data.update(
            {
                "name": self.name,
                "title": self.title,
                "path": self.path,
                "component": self.component,
                "icon": self.icon,
                "parent_id": self.parent_id,
                "type": self.type,
                "is_hidden": self.is_hidden,
                "is_keepalive": self.is_keepalive,
                "sort_order": self.sort_order,
                "permission_code": self.permission_code,
                "description": self.description,
            }
        )
        return data
